﻿//-------------------------------------------------------------------------------------
// All Rights Reserved , Copyright (C) 2011 , DotNet, Ltd.
//-------------------------------------------------------------------------------------

using System;
using System.Data;

namespace DotNet.Business
{
    using DotNet.BaseManager;
    using DotNet.DbUtilities;
    using DotNet.Model;
    using DotNet.Utilities;

    /// <summary>
    /// BasePermissionManager
    /// 资源权限管理，操作权限管理（这里喊了用户操作权限，角色的操作权限）
    ///
    /// 修改纪录
    ///
    ///     2010.09.21 版本：2.0 DotNet 智能权限判断、后台自动增加权限，增加并发锁PermissionItemLock。
    ///     2009.09.22 版本：1.1 DotNet 前台判断的权限，后台都需要记录起来，防止后台缺失前台的判断权限。
    ///     2008.03.28 版本：1.0 DotNet 创建主键。
    ///
    /// 版本：1.0
    ///
    /// <author>
    ///		<name>DotNet</name>
    ///		<date>2008.03.28</date>
    /// </author>
    /// </summary>
    public partial class BasePermissionManager : BaseManager, IBaseManager
    {
        private static readonly object PermissionItemLock = new object();

        #region public bool PermissionExists(string permissionItemId, string resourceCategory, string resourceId) 检查是否存在

        /// <summary>
        /// 检查是否存在
        /// </summary>
        /// <param name="permissionItemId">权限主键</param>
        /// <param name="resourceCategory">资源分类</param>
        /// <param name="resourceId">资源主键</param>
        /// <returns>是否存在</returns>
        public bool PermissionExists(string permissionItemId, string resourceCategory, string resourceId)
        {
            bool returnValue = true;
            string[] names = new string[3];
            string[] values = new string[3];
            names[0] = BasePermissionTable.FieldResourceCategory;
            values[0] = resourceCategory;
            names[1] = BasePermissionTable.FieldResourceId;
            values[1] = resourceId;
            names[2] = BasePermissionTable.FieldPermissionId;
            values[2] = permissionItemId;

            // 检查是否存在
            if (!this.Exists(names, values))
            {
                returnValue = false;
            }
            return returnValue;
        }

        #endregion public bool PermissionExists(string permissionItemId, string resourceCategory, string resourceId) 检查是否存在

        #region public string AddPermission(BasePermissionEntity resourcePermissionEntity) 添加

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="resourcePermissionEntity">实体</param>
        /// <param name="statusCode">返回状态码</param>
        /// <returns>主键</returns>
        public string AddPermission(BasePermissionEntity resourcePermissionEntity)
        {
            string returnValue = string.Empty;

            // 检查记录是否重复
            if (!this.PermissionExists(resourcePermissionEntity.PermissionId.ToString(), resourcePermissionEntity.ResourceCategory, resourcePermissionEntity.ResourceId))
            {
                returnValue = this.AddEntity(resourcePermissionEntity);
            }
            return returnValue;
        }

        #endregion public string AddPermission(BasePermissionEntity resourcePermissionEntity) 添加

        //
        // ResourcePermission 权限判断
        //

        #region public bool CheckPermissionByUser(string userId, string permissionItemCode) 是否有相应的权限

        /// <summary>
        /// 是否有相应的权限
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <param name="permissionItemCode">权限编号</param>
        /// <returns>是否有权限</returns>
        public bool CheckPermissionByUser(string userId, string permissionItemCode)
        {
            // 先判断用户类别
            if (UserInfo.IsAdministrator)
            {
                return true;
            }

            // 判断当前判断的权限是否存在，否则很容易出现前台设置了权限，后台没此项权限
            // 需要自动的能把前台判断过的权限，都记录到后台来
            BasePermissionItemManager permissionItemManager = new BasePermissionItemManager(DbHelper, UserInfo);

            string[] names = new string[] { BasePermissionItemTable.FieldDeletionStateCode, BasePermissionItemTable.FieldEnabled, BasePermissionItemTable.FieldCode };
            object[] values = new object[] { 0, 1, permissionItemCode };

            string permissionItemId = permissionItemManager.GetProperty(names, values, BasePermissionItemTable.FieldId);

            // 若是在调试阶段、有没在的权限被判断了，那就自动加入这个权限，不用人工加入权限了，工作效率会提高很多，
            // 哪些权限是否有被调用什么的，还可以进行一些诊断
#if (DEBUG)
            if (String.IsNullOrEmpty(permissionItemId))
            {
                // 这里需要进行一次加锁，方式并发冲突发生
                lock (PermissionItemLock)
                {
                    BasePermissionItemEntity permissionItemEntity = new BasePermissionItemEntity();
                    permissionItemEntity.Code = permissionItemCode;
                    permissionItemEntity.FullName = permissionItemCode;
                    permissionItemEntity.ParentId = null;
                    permissionItemEntity.IsScope = 0;
                    permissionItemEntity.AllowDelete = 1;
                    permissionItemEntity.AllowEdit = 1;
                    permissionItemEntity.Enabled = 1;

                    // 这里是防止主键重复？
                    // permissionEntity.ID = BaseBusinessLogic.NewGuid();
                    permissionItemManager.AddEntity(permissionItemEntity);
                }
            }
            else
            {
                // 更新最后一次访问日期，设置为当前服务器日期
                SQLBuilder sqlBuilder = new SQLBuilder(DbHelper);
                sqlBuilder.BeginUpdate(BasePermissionItemTable.TableName);
                sqlBuilder.SetDBNow(BasePermissionItemTable.FieldLastCall);
                sqlBuilder.SetWhere(BasePermissionItemTable.FieldId, permissionItemId);
                sqlBuilder.EndUpdate();
            }
#endif

            // 没有找到相应的权限
            if (String.IsNullOrEmpty(permissionItemId))
            {
                return false;
            }

            // 判断用户权限
            if (this.CheckUserPermission(userId, permissionItemId))
            {
                return true;
            }

            // 判断用户角色权限
            if (this.CheckUserRolePermission(userId, permissionItemId))
            {
                return true;
            }
            return false;
        }

        #endregion public bool CheckPermissionByUser(string userId, string permissionItemCode) 是否有相应的权限

        #region private bool CheckUserPermission(string userId, string permissionItemId)

        /// <summary>
        /// 职员是否有模块权限
        /// </summary>
        /// <param name="userId">用户主键</param>
        /// <param name="permissionItemId">权限主键</param>
        /// <returns>是否有权限</returns>
        private bool CheckUserPermission(string userId, string permissionItemId)
        {
            return CheckResourcePermission("User", userId, permissionItemId);
        }

        #endregion private bool CheckUserPermission(string userId, string permissionItemId)

        private bool CheckResourcePermission(string resourceCategory, string resourceId, string permissionItemId)
        {
            string sqlQuery = " SELECT COUNT(1) "
                             + "   FROM " + BasePermissionTable.TableName
                             + "  WHERE (" + BasePermissionTable.FieldResourceCategory + " = '" + resourceCategory + "') "
                             + "        AND (" + BasePermissionTable.FieldEnabled + " = 1) "
                             + "        AND (" + BasePermissionTable.FieldDeletionStateCode + " = 0) "
                             + "        AND (" + BasePermissionTable.FieldResourceId + " = '" + resourceId + "') "
                             + "        AND (" + BasePermissionTable.FieldPermissionId + " = '" + permissionItemId + "')";
            int rowCount = 0;
            object returnObject = DbHelper.ExecuteScalar(sqlQuery);
            if (returnObject != null)
            {
                rowCount = int.Parse(returnObject.ToString());
            }
            return rowCount > 0;
        }

        #region private bool CheckUserRolePermission(string userId, string permissionItemId)

        /// <summary>
        /// 用户角色关系是否有模块权限
        /// </summary>
        /// <param name="dbHelper">数据库连接</param>
        /// <param name="userId">用户主键</param>
        /// <param name="permissionItemId">权限主键</param>
        /// <returns>有角色权限</returns>
        private bool CheckUserRolePermission(string userId, string permissionItemId)
        {
            string sqlQuery = " SELECT COUNT(1) "
                            + "   FROM " + BasePermissionTable.TableName
                            + "  WHERE " + "(" + BasePermissionTable.FieldResourceCategory + " = 'Role') "
                            + "        AND (" + BasePermissionTable.FieldEnabled + " = 1 "
                            + "        AND  " + BasePermissionTable.FieldDeletionStateCode + " = 0) "
                            + "        AND (" + BasePermissionTable.FieldResourceId + " IN ( "
                                                + " SELECT " + BaseUserRoleTable.FieldRoleId
                                                + "   FROM " + BaseUserRoleTable.TableName
                                                + "  WHERE " + BaseUserRoleTable.FieldUserId + " = '" + userId + "' "
                                                + "        AND " + BaseUserRoleTable.FieldEnabled + " = 1 "
                                                + "        AND " + BaseUserRoleTable.FieldDeletionStateCode + " = 0 "
                                                + "  UNION "
                                                + " SELECT " + BaseUserTable.FieldRoleId
                                                + "   FROM " + BaseUserTable.TableName
                                                + "  WHERE " + BaseUserTable.FieldId + " = '" + userId + "'"
                                                + ") ) "
                            + "        AND (" + BasePermissionTable.FieldPermissionId + " = '" + permissionItemId + "') ";
            int rowCount = 0;
            object returnObject = DbHelper.ExecuteScalar(sqlQuery);
            if (returnObject != null)
            {
                rowCount = int.Parse(returnObject.ToString());
            }
            return rowCount > 0;
        }

        #endregion private bool CheckUserRolePermission(string userId, string permissionItemId)

        //
        // 从数据库获取权限
        //

        #region public DataTable GetPermission(BaseUserInfo userInfo)

        /// <summary>
        /// 获得一个职员的某一模块的权限
        /// </summary>
        /// <param name="dbHelper">数据库连接</param>
        /// <param name=userInfo>用户</param>
        /// <returns>数据表</returns>
        public DataTable GetPermission(BaseUserInfo userInfo)
        {
            BasePermissionItemManager permissionItemManager = new BasePermissionItemManager(DbHelper, userInfo);
            if (userInfo.IsAdministrator)
            {
                return permissionItemManager.GetDataTable(BasePermissionItemTable.FieldEnabled, "1", BasePermissionItemTable.FieldSortCode);
            }
            return this.GetPermissionByUser(userInfo.Id);
        }

        #endregion public DataTable GetPermission(BaseUserInfo userInfo)

        public DataTable GetPermissionByUser(string userId)
        {
            string sqlQuery = " SELECT * "
                             + "   FROM " + BasePermissionItemTable.TableName
                             + "  WHERE " + BasePermissionItemTable.FieldEnabled + " = 1 "
                             + "        AND " + BasePermissionItemTable.FieldId + " IN ( "

                             // 用户的权限
                             + " SELECT " + BasePermissionTable.FieldPermissionId
                             + "   FROM " + BasePermissionTable.TableName
                             + "  WHERE (" + BasePermissionTable.FieldResourceCategory + " = 'User') "
                             + "        AND (" + BasePermissionTable.FieldEnabled + " = 1) "
                             + "        AND (" + BasePermissionTable.FieldResourceId + " = '" + userId + "')"

                            + " UNION "

                            // 角色的权限
                            + " SELECT " + BasePermissionTable.FieldPermissionId
                            + "   FROM " + BasePermissionTable.TableName
                            + "  WHERE " + "(" + BasePermissionTable.FieldResourceCategory + " = 'Role') "
                            + "        AND (" + BasePermissionTable.FieldEnabled + " = 1) "
                            + "        AND (" + BasePermissionTable.FieldResourceId + " IN ( "
                                                + " SELECT " + BaseUserRoleTable.FieldRoleId
                                                + "   FROM " + BaseUserRoleTable.TableName
                                                + "  WHERE " + BaseUserRoleTable.FieldUserId + " = '" + userId + "' "
                                                + "        AND " + BaseUserRoleTable.FieldEnabled + " = 1"
                                                + "  UNION "
                                                + " SELECT " + BaseUserTable.FieldRoleId
                                                + "   FROM " + BaseUserTable.TableName
                                                + "  WHERE " + BaseUserTable.FieldId + " = '" + userId + "'"
                                                + ")) "
                            + ") "
                            + " ORDER BY " + BasePermissionItemTable.FieldSortCode;

            return DbHelper.Fill(sqlQuery);
        }

        #region private bool CheckPermissionByRole(string roleId, string permissionItemCode)

        /// <summary>
        /// 用户角色关系是否有模块权限
        /// </summary>
        /// <param name="roleId">角色主键</param>
        /// <param name="permissionItemCode">权限编号</param>
        /// <returns>有角色权限</returns>
        public bool CheckPermissionByRole(string roleId, string permissionItemCode)
        {
            BasePermissionItemManager permissionItemManager = new BasePermissionItemManager(DbHelper, UserInfo);
            string permissionItemId = permissionItemManager.GetProperty(BasePermissionItemTable.FieldCode, permissionItemCode, BasePermissionItemTable.FieldId);

            // 判断当前判断的权限是否存在，否则很容易出现前台设置了权限，后台没此项权限
            // 需要自动的能把前台判断过的权限，都记录到后台来
#if (DEBUG)
            if (String.IsNullOrEmpty(permissionItemId))
            {
                BasePermissionItemEntity permissionItemEntity = new BasePermissionItemEntity();
                permissionItemEntity.Code = permissionItemCode;
                permissionItemEntity.FullName = permissionItemCode;
                permissionItemEntity.ParentId = 0;
                permissionItemEntity.IsScope = 0;
                permissionItemEntity.AllowDelete = 1;
                permissionItemEntity.AllowEdit = 1;
                permissionItemEntity.Enabled = 1;

                // 这里是防止主键重复？
                // permissionEntity.ID = BaseBusinessLogic.NewGuid();
                permissionItemManager.AddEntity(permissionItemEntity);
            }
            else
            {
                // 更新最后一次访问日期，设置为当前服务器日期
                SQLBuilder sqlBuilder = new SQLBuilder(DbHelper);
                sqlBuilder.BeginUpdate(BasePermissionItemTable.TableName);
                sqlBuilder.SetDBNow(BasePermissionItemTable.FieldLastCall);
                sqlBuilder.SetWhere(BasePermissionItemTable.FieldId, permissionItemId);
                sqlBuilder.EndUpdate();
            }
#endif

            if (string.IsNullOrEmpty(permissionItemId))
            {
                return false;
            }
            string sqlQuery = " SELECT COUNT(*) "
                            + "   FROM " + BasePermissionTable.TableName
                            + "  WHERE " + "(" + BasePermissionTable.FieldResourceCategory + " = 'Role') "
                            + "        AND (" + BasePermissionTable.FieldEnabled + " = 1) "
                            + "        AND (" + BasePermissionTable.FieldResourceId + " = '" + roleId + "' ) "
                            + "        AND (" + BasePermissionTable.FieldPermissionId + " = '" + permissionItemId + "') ";
            int rowCount = 0;
            object returnObject = DbHelper.ExecuteScalar(sqlQuery);
            if (returnObject != null)
            {
                rowCount = int.Parse(returnObject.ToString());
            }
            return rowCount > 0;
        }

        #endregion private bool CheckPermissionByRole(string roleId, string permissionItemCode)
    }
}